package com.dp.mallchat.common.common.aspect;

import cn.hutool.core.util.StrUtil;
import com.dp.mallchat.common.common.annotation.MyRedissonLock;
import com.dp.mallchat.common.common.lock.LockService;
import com.dp.mallchat.common.common.utils.SpElUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author: dupeng
 * @CreateTime: 2024-06-06  18:36
 * @Description: 自定义redisson锁切面
 */
@Aspect
@Component
@Slf4j
@Order(0)
public class MyRedissonLockAspect {

    @Autowired
    private LockService lockService;


    @Around("@annotation(com.dp.mallchat.common.common.annotation.MyRedissonLock)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        MyRedissonLock myRedissonLock = method.getAnnotation(MyRedissonLock.class);
        String prefix = StrUtil.isBlank(myRedissonLock.prefixKey()) ? SpElUtils.getMethodKey(method) : myRedissonLock.prefixKey();//默认方法限定名+注解排名（可能多个）
        String key = SpElUtils.parseSpEl(method, joinPoint.getArgs(), myRedissonLock.key());
        return lockService.executeWithLock(prefix + ":" + key, myRedissonLock.waitTime(), myRedissonLock.timeUnit(), joinPoint::proceed);
    }


}
